/**
 * 
 */
package pl.edu.agh.to;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;

/**
 * @author karulis
 * 
 */
public class DBAccess extends Observable implements IDBAccess {

	static DBAccess mInstance;
	private final DatabaseHelper databaseHelper;
	private static final String dbName = "organizerDB";

	/**
	 * @return the databaseHelper
	 */
	public DatabaseHelper getDatabaseHelper() {
		return databaseHelper;
	}

	List<Participant> participants = new ArrayList<Participant>();
	List<Course> courses = new ArrayList<Course>();

	private DBAccess(TemplateActivity activity) {
		databaseHelper = new DatabaseHelper(activity, dbName, 11);

		// TODO test content
		addParticipant(new Participant("Zaneta", "Ruda"));
		addParticipant(new Participant("Asia", "Fajna"));
		addParticipant(new Participant("Ewelinka", "Elelewinka"));
		addParticipant(new Participant("Ania", "Zapominalska"));

		addCourse(new Course("TO", "grup1"));
		addCourse(new Course("SE", "grup1"));
		addCourse(new Course("MN", "grup1"));

		participants = getDatabaseHelper().getParticipants();
		courses = getDatabaseHelper().getCourses();
	}

	// TODO inconsistent with interface
	static public DBAccess instance(TemplateActivity activity) {
		if (mInstance == null) {
			mInstance = new DBAccess(activity);
		}
		return mInstance;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see pl.edu.agh.to.IDBAccess#getParticipants(java.lang.String)
	 */
	@Override
	public List<Object> getParticipants(String course) {
		if (course != null && getCourse(course) != null) {
			return toObjectList(getDatabaseHelper().getParticipants(
					getCourse(course)));
		}
		return new ArrayList<Object>();
	}

	private List<Object> toObjectList(List<? extends Object> list) {
		List<Object> strList = new ArrayList<Object>();
		for (Object obj : list) {
			strList.add(obj);
		}
		return strList;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see pl.edu.agh.to.IDBAccess#getCourses(java.lang.String)
	 */
	@Override
	public List<Object> getCourses(String participant) {
		if (participant != null) {
			return toObjectList(getDatabaseHelper().getCourses(
					getParticipant(participant)));
		}
		return new ArrayList<Object>();
	}

	@Override
	public Course getCourse(String name) {
		for (Course course : courses) {
			if (course.toString().equals(name)) {
				return course;
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see pl.edu.agh.to.IDBAccess#getRates(java.lang.String, java.lang.String)
	 */
	@Override
	public List<Object> getRates(String participant, String course) {
		Participant part = getParticipant(participant);
		Course cour = getCourse(course);
		if (part != null && cour != null) {
			return getDatabaseHelper().getRates(getParticipant(participant),
					getCourse(course));

		}
		return new ArrayList<Object>();
	}

	@Override
	public List<Object> getAllCourses() {
		return toObjectList(courses);
	}

	@Override
	public List<Object> getAllParticipants() {
		return toObjectList(participants);
	}

	@Override
	public List<Object> getScheduleFor(String day) {
		return getDatabaseHelper().getScheduleFor(day);
	}

	@Override
	public void removeCourse(String courseName) {
		if (courseName != null && getCourse(courseName) != null) {
			getDatabaseHelper().deleteCourse(getCourse(courseName));
			courses.remove(getCourse(courseName));
			setChanged();
			notifyObservers(DBChange.CourseChange);
		}
	}

	@Override
	public void addCourse(Course course) {
		if (course != null) {
			courses.add(course);
			getDatabaseHelper().insertCourse(course);
			setChanged();
			notifyObservers(DBChange.CourseChange);
		}
	}

	@Override
	public void updateCourse(Course oldCourse, Course newCourse) {
		if (oldCourse != null && newCourse != null) {
			courses.remove(oldCourse);
			courses.add(newCourse);
			getDatabaseHelper().updateCourse(oldCourse, newCourse);
			setChanged();
			notifyObservers(DBChange.CourseChange);
		}
	}

	@Override
	public void updateParticipant(Participant oldParticipant,
			Participant newParticipant) {
		if (oldParticipant != null && newParticipant != null) {
			participants.remove(oldParticipant);
			participants.add(newParticipant);
			getDatabaseHelper().updateParticipant(oldParticipant,
					newParticipant);
			setChanged();
			notifyObservers(DBChange.ParticipantChange);
		}
	}

	@Override
	public void removeParticipant(String name) {
		if (name != null && getParticipant(name) != null) {
			getDatabaseHelper().deleteParticipant(getParticipant(name));
			participants.remove(getParticipant(name));
			setChanged();
			notifyObservers(DBChange.ParticipantChange);
		}
	}

	@Override
	public Participant getParticipant(String name) {
		for (Participant participant : participants) {
			if (participant.toString().equals(name)) {
				return participant;
			}
		}
		return null;
	}

	@Override
	public void addParticipant(Participant participant) {
		if (participant != null) {
			participants.add(participant);
			getDatabaseHelper().insertParticipant(participant);

			setChanged();
			notifyObservers(DBChange.ParticipantChange);
		}
	}

	@Override
	public void addParticipantToCourse(String participant, String course) {
		if (participant != null && getParticipant(participant) != null
				&& course != null && getCourse(course) != null) {
			getDatabaseHelper().insertAttend(getParticipant(participant),
					getCourse(course));
			setChanged();
			notifyObservers(DBChange.AttendChange);
		}
	}

	@Override
	public void removeParticipantFromCourse(String participant, String course) {
		if (participant != null && getParticipant(participant) != null
				&& course != null && getCourse(course) != null) {
			getDatabaseHelper().deleteAttend(getParticipant(participant),
					getCourse(course));
			setChanged();
			notifyObservers(DBChange.AttendChange);
		}
	}

	@Override
	public void addRate(String participant, String course, Rate rate) {
		if (participant != null && getParticipant(participant) != null
				&& course != null && getCourse(course) != null && rate != null) {
			getDatabaseHelper().insertRate(getParticipant(participant),
					getCourse(course), rate);
			setChanged();
			notifyObservers(DBChange.RateChange);
		}
	}

	@Override
	public void removeRate(String participant, String course, Rate rate) {
		if (participant != null && getParticipant(participant) != null
				&& course != null && getCourse(course) != null && rate != null) {
			getDatabaseHelper().deleteRate(getParticipant(participant),
					getCourse(course), rate);
			setChanged();
			notifyObservers(DBChange.RateChange);
		}
	}

	@Override
	public void addSchedule(ScheduleItem scheduleItem) {
		if (scheduleItem != null) {
			getDatabaseHelper().insertSchedule(scheduleItem);
			setChanged();
			notifyObservers(DBChange.ScheduleChange);
		}
	}

	@Override
	public void removeSchedule(ScheduleItem scheduleItem) {
		if (scheduleItem != null) {
			getDatabaseHelper().deleteSchedule(scheduleItem);
			setChanged();
			notifyObservers(DBChange.ScheduleChange);
		}
	}
}
